package com;

import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;

import com.gp.Chrome;
import com.gp.ChromeFactory;
import com.gp.Cross;
import com.gp.Fitness;
import com.gp.Mutation;
import com.gp.Selection;
import com.stock.Stock;
import com.stock.StockData;
import com.utils.CONST;
import com.utils.Feeder;
import com.utils.Random;
import com.utils.Serializer;
 
public class Main {

	/**
	 * @param args
	 */
	
	public static void main(String[] args) {
		if(args.length < 5){
			System.out.println(args.length);
			return;
		}
		
		String action = args[0].trim();
		int days = Integer.valueOf(args[1].trim());
		String datafolder = args[2].trim();
		String filenames  = args[3].trim();
		String modelfile = args[4].trim();
		
		
		if(action.equals("-t")){
			Training(days,datafolder ,filenames ,modelfile);
		}else {
			if(args.length < 6){
				System.out.println(args.length);
				return;
			}
			String buyfile = args[5].trim();
			Processing(days,datafolder ,filenames ,modelfile, buyfile);
		}
				
	}
	
	public static void Training(int days, String datafolder,String filenames ,String modelfile) {
		List<String> stockList = Feeder.ReadFilesNames(filenames);
		List<Stock> allStocks = Feeder.Feed(datafolder, stockList);
		HashMap<String, Chrome> chromeMap =new HashMap<String, Chrome>();
		
		for (Stock stock : allStocks) {
			List<Chrome> generation = ChromeFactory.createGeneration(CONST.TREE_START_SIZE, CONST.GENERATION_SIZE);
			
			int currDay = 0;
			int toDay = 0;
			Chrome bestChrome = null;
			for (int index = 0; index < CONST.ROUNDS; index++) {
				
				currDay = Random.nextInt(stock.getDayNumber() - days - 1);
				toDay = currDay+days; 
				StockData curr = stock.getDay(currDay);
				StockData to = stock.getDay(toDay);
				
				Fitness.updateFit(generation, curr, to);
				Selection selection = new Selection(generation);
				bestChrome = selection.getBestChrome();
				
				List<Chrome> newGeneration = new LinkedList<Chrome>();
				for (int i = 0; i < generation.size() -1; i++) {
					Chrome ch1 = selection.rolleteSelection();
					Chrome ch2 = selection.rolleteSelection();
					Chrome newCh = Cross.cross(ch1, ch2);
					Mutation.roughMutation(newCh);
					newGeneration.add(newCh);
					
				}
				newGeneration.add(selection.getBestChrome());
				generation = newGeneration;
			}
			
			chromeMap.put(stock.getName(), bestChrome);
		}
		Serializer.ObjectToFile(chromeMap, modelfile);

	}
	
	public static void Processing(int days, String datafolder,String filenames ,String modelfile,String buyFile) {
		
		List<String> stockList = Feeder.ReadFilesNames( filenames); 
		List<Stock> allStocks = Feeder.Feed(datafolder, stockList);
		
		@SuppressWarnings("unchecked")
		HashMap<String, Chrome> chromeMap = (HashMap<String, Chrome>) Serializer.FileToObject(modelfile);
		
		try {
			FileWriter outFile = new FileWriter(buyFile);
			PrintWriter out = new PrintWriter(outFile);
			for (Stock stock: allStocks) {
				int buyDay = stock.getDayNumber() - 1;
				Chrome currChrome = chromeMap.get(stock.getName());
				StockData currData = stock.getDay(buyDay);
				double change =  currChrome.getValue(currData) - currData.getClosingPrice();
				
				if(change > CONST.CHANGE_LIMIT){
					out.println(stock.getName().replaceFirst(".csv", ""));
				}
			}
			out.close();
			outFile.close();
		} catch (IOException e) {

		}
		
		
			
			
		
	}

}